////////////////////////////////////////////////////////////////////////////
//	D2DGraphicsWrapper.h & D2DGraphicsWrapper.cpp
//		Class that serves as a wrapper to all Direct2D interfaces and the
//		Windows Multimedia Library. It contains functions to load and draw
//		bitmaps and some D2D primitives.
//
//	Author:					Daniel Lima - April 2012
/////////////////////////////////////////////////////////////////////////////

#ifndef D2D_GRAPHICS_WRAPPER
#define D2D_GRAPHICS_WRAPPER

// Everything we need for Direct2D
#include <d2d1.h>							// Include the Direct2D API.
#pragma comment(lib, "d2d1.lib")			// Connect to the Direct2D Import Library.
#include <dwrite.h>							// Include the DirectWrite API.
#pragma comment(lib, "dwrite.lib")			// Connect to the DirectWrite Import Library.
#include <wincodec.h>						// Include the Windows Imaging Component
#pragma comment(lib, "windowscodecs.lib")	// Connect to the Windows Imaging Component

// Include the Windows Multimedia Library:
#include <mmsystem.h>						// Multimedia header file.
#pragma comment(lib, "winmm.lib")			// Multimedia import library.

// Vector of bitmaps
#include <vector>

// Necessary to be able to easily print data to the console window
#include <iostream>
#ifdef _DEBUG
#define LOG(info) std::cout << info << std::endl;
#else
#define LOG(info)
#endif

// Using multi-byte character set
#include <tchar.h>

// Direct2D Helper Functions & Macros:
#define D2DColor(clr)		D2D1::ColorF(D2D1::ColorF::clr)
#define D2DHex(hex)			D2D1::ColorF(hex)
#define point(x,y)			D2D1::Point2F(x,y)
#define circle(cx,cy,rx,ry) D2D1::Ellipse(point(cx,cy),rx,ry)

class D2DGraphicsWrapper
{
	// Singleton's static instance
	static D2DGraphicsWrapper* sm_pInstance;

	// Direct2D Interfaces
	ID2D1Factory*				m_pD2DFactory;
	ID2D1HwndRenderTarget*		m_pRenderTarget;
	ID2D1SolidColorBrush*		m_pBrush;
	D2D1_MATRIX_3X2_F			m_matBox;

	// DirectWrite Interfaces:
	IDWriteFactory*				m_pDWFactory;
	IDWriteTextFormat*			m_pTextFormat;

	// Windows Imaging Component Interfaces:
	IWICImagingFactory*			m_pWICFactory;
	std::vector<ID2D1Bitmap*>	m_vpBitmapManager;

	// Constructor - Initialize all variables to default values
	D2DGraphicsWrapper(void);

	// For a proper singleton, the trilogy needs to be defined
	D2DGraphicsWrapper(const D2DGraphicsWrapper&) {}					// Copy Constructor
	D2DGraphicsWrapper& operator=(const D2DGraphicsWrapper&) {}			// Assignment Operator
	~D2DGraphicsWrapper(void) {}										// Destructor

	// Creates a Direct2D bitmap from the specified file name.
	ID2D1Bitmap* LoadBitmap(PCWSTR wszFilename, UINT uiDestWidth, UINT uiDestHeight);

	// Draw a bitmap
	void DrawBitmap(ID2D1Bitmap* pBitmap, const D2D1_RECT_F& DestRect, float fOpacity = 1.0f,
		D2D1_BITMAP_INTERPOLATION_MODE interpolationMode = D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR,
		const D2D1_RECT_F* pSourceRect = nullptr);

	// Used to delete the singleton's instance
	static void DeleteInstance(void);

	template<class Interface>
	inline void SafeRelease(Interface **ppInterfaceToRelease)
	{
		if (*ppInterfaceToRelease != NULL)
		{
			(*ppInterfaceToRelease)->Release();
			(*ppInterfaceToRelease) = NULL;
		}
	}

public:
	// Used to access the singleton's instance
	static D2DGraphicsWrapper* GetInstance(void);

	// Used to initialize all graphic interfaces
	HRESULT Initialize(HWND hWnd);

	// Start drawing
	void StartDrawing(void);

	// Load bitmap in the bitmap array
	int Load(PCWSTR wszFilename, UINT uiDestWidth, UINT uiDestHeight);

	// Render bitmap from the bitmap array
	void Draw(int nBitmapID, const RECT& rectDestination, float fOpacity = 1.0f,
		const RECT* rectSource = nullptr);
	void Draw(int nBitmapID, float fPosX, float fPosY, float fOpacity = 1.0f,
		const RECT* rectSource = nullptr);

	// Stop drawing
	void StopDrawing(HWND hWnd);


	// Used to uninitialize all graphic interfaces
	void Shutdown(void);
};


#endif

